<template>
    <yh-dialog :title="title" width="800px" :visible.sync="visibleTemp" :close-on-click-modal="false" drag>
        <div class="dialog-main-body" v-loading="loading">
            <div class="dialog-main-body-box">
                <div class="dialog-main-body-box-hd">未选部分</div>
                <draggable
                    class="dialog-main-body-box-content right-content"
                    v-model="noneSelected"
                    group="box"
                    animation="300"
                    :key="noneSelected.length"
                >
                    <transition-group class="dialog-box-group">
                        <div class="dialog-box-group-item" v-for="item in noneSelected" :key="item.id">{{ item.content }}</div>
                    </transition-group>
                </draggable>
            </div>
            <div class="dialog-main-body-box">
                <div class="dialog-main-body-box-hd">已选部分</div>
                <div class="dialog-main-body-box-fixed" v-if="fixedFieldList.length">
                    <div class="dialog-box-group-item is-disabled" v-for="item in fixedFieldList" :key="item.id">
                        {{ item.content }}
                    </div>
                </div>
                <draggable class="dialog-main-body-box-content" v-model="selected" group="box" animation="300" :key="selected.length">
                    <transition-group class="dialog-box-group">
                        <div class="dialog-box-group-item" v-for="item in selected" :key="item.id">
                            {{ item.content }}
                        </div>
                    </transition-group>
                </draggable>
            </div>
        </div>
        <div slot="footer" class="dialog-footer">
            <el-button size="mini" @click="reset">重置</el-button>
            <el-button size="mini" @click="visibleTemp = false">取 消</el-button>
            <el-button size="mini" type="primary" @click="onSubmit" v-loading="loading">确 定</el-button>
        </div>
    </yh-dialog>
</template>

<script lang="ts">
import { Vue, Component, Prop, Watch, Emit } from 'vue-property-decorator';
import draggable from 'vuedraggable';
type TFieldItem = { id: string; content: string };

@Component({ name: 'RiskTableLayout', components: { draggable } })
export default class RiskTableLayout extends Vue {
    created() {
        const fieldList = JSON.parse(JSON.stringify(this.fieldList));
        const selectedFieldList = JSON.parse(JSON.stringify(this.selectedFieldList));
        const fixedFieldList = JSON.parse(JSON.stringify(this.fixedFieldList));
        this.filterList(fieldList, selectedFieldList, fixedFieldList);
    }
    // 标题
    @Prop({ default: '页面布局' }) readonly title: string;
    // 显隐
    @Prop({ default: false }) readonly visible!: boolean;
    // 表名
    @Prop({ required: true }) readonly tableName!: string;
    // 字段列表
    @Prop({ default: () => [] }) readonly fieldList!: TFieldItem[];
    // 已选择字段列表
    @Prop({ default: () => [] }) readonly selectedFieldList!: TFieldItem[];
    // 固定的字段
    @Prop({ default: () => [] }) readonly fixedFieldList!: TFieldItem[];

    // 重置时未选字段
    @Prop({ default: () => [] }) readonly resetNoSelectedFieldList: TFieldItem[];

    // 组件内部使用
    private visibleTemp: boolean = false;
    private loading: boolean = false;
    // 组件内部两个列表
    // private drag = false;
    private selected: TFieldItem[] = [];
    private noneSelected: TFieldItem[] = [];

    @Watch('visible')
    onWatchVisible(value: boolean) {
        this.visibleTemp = value;
        if (value) {
            const fieldList = JSON.parse(JSON.stringify(this.fieldList));
            const selectedFieldList = JSON.parse(JSON.stringify(this.selectedFieldList));
            const fixedFieldList = JSON.parse(JSON.stringify(this.fixedFieldList));
            this.filterList(fieldList, selectedFieldList, fixedFieldList);
        }
    }

    @Watch('visibleTemp')
    onWatchVisibleTemp(value: boolean) {
        if (value !== this.visible) {
            this.$emit('update:visible', value);
        }
    }

    @Watch('fieldList', { deep: true })
    onWatchFieldList(value: TFieldItem[], oldValue: TFieldItem[]) {
        if (JSON.stringify(value) !== JSON.stringify(oldValue)) {
            const fieldList = JSON.parse(JSON.stringify(value));
            const selectedFieldList = JSON.parse(JSON.stringify(this.selectedFieldList));
            const fixedFieldList = JSON.parse(JSON.stringify(this.fixedFieldList));
            this.filterList(fieldList, selectedFieldList, fixedFieldList);
        }
    }

    @Watch('selectedFieldList', { deep: true })
    onWatchSelectedFieldList(value: TFieldItem[], oldValue: TFieldItem[]) {
        if (JSON.stringify(value) !== JSON.stringify(oldValue)) {
            const fieldList = JSON.parse(JSON.stringify(this.fieldList));
            const selectedFieldList = JSON.parse(JSON.stringify(value));
            const fixedFieldList = JSON.parse(JSON.stringify(this.fixedFieldList));
            this.filterList(fieldList, selectedFieldList, fixedFieldList);
        }
    }

    @Watch('fixedFieldList', { deep: true })
    onWatchFixedFieldList(value: TFieldItem[], oldValue: TFieldItem[]) {
        if (JSON.stringify(value) !== JSON.stringify(oldValue)) {
            const fieldList = JSON.parse(JSON.stringify(this.fieldList));
            const selectedFieldList = JSON.parse(JSON.stringify(this.selectedFieldList));
            const fixedFieldList = JSON.parse(JSON.stringify(value));
            this.filterList(fieldList, selectedFieldList, fixedFieldList);
        }
    }

    /**
     * 过滤数据
     * @param allList 表格全部字段
     * @param selectedList 表格已选择字段
     * @param fixedList 表格固定字段
     */
    filterList(allList: TFieldItem[], selectedList: TFieldItem[], fixedList: TFieldItem[]) {
        // 1. 获取固定 keys
        const fixedKeys = fixedList.map((item) => item.id);
        // 2. 剔除固定值，获取全部列表
        const all = allList.filter((item) => {
            return !fixedKeys.includes(item.id);
        });
        // 3. 获取已选择的列表
        const selected = selectedList.filter((selectedItem) => {
            const value = all.find((allItem) => {
                return allItem.id === selectedItem.id;
            });
            return !!value;
        });
        // 4. 获取未选择的列表
        const noneSelected = all.filter((allItem) => {
            const value = selectedList.find((selectedItem) => {
                return allItem.id === selectedItem.id;
            });
            return !value;
        });
        this.selected = selected;
        this.noneSelected = noneSelected;
    }

    // 重置
    reset() {
        // 1. 获取固定 keys
        const fixedKeys = this.fixedFieldList.concat(this.resetNoSelectedFieldList).map((item) => item.id);

        // 2. 剔除固定值，获取全部列表
        this.selected = this.fieldList.filter((item) => {
            return !fixedKeys.includes(item.id);
        });
        // this.selected = JSON.parse(JSON.stringify([...this.selected, ...this.noneSelected]));

        this.noneSelected = this.resetNoSelectedFieldList;
    }
    @Emit()
    onSubmit() {
        // if (!this.selected.length) {
        //     this.yh_message_error('表格字段不能为空');
        //     // eslint-disable-next-line prefer-promise-reject-errors
        //     return Promise.reject(null);
        // }
        const data = {
            showField: JSON.stringify(this.selected),
            tableName: this.tableName,
        };
        return new Promise((resolve) => {
            this.loading = true;
            this.$axios
                .post('/tableLayout/insert', data)
                .then(() => {
                    // this.$message({
                    //     type: 'success',
                    //     message: '修改成功',
                    //     duration: 1000,
                    //     showClose: true,
                    // });
                    this.yh_message_success('修改成功');
                    this.visibleTemp = false;
                    resolve({
                        fixed: this.fixedFieldList,
                        selected: this.selected,
                    });
                })
                .finally(() => {
                    this.loading = false;
                });
        });
    }
    // 开始拖拽事件
    onStart() {
        // this.drag = true;
    }
    // 拖拽结束事件
    onEnd() {
        // this.drag = false;
    }
}
</script>

<style lang="scss" scoped>
.dialog-main-body {
    height: 345px;
    display: flex;
    justify-content: space-between;

    .dialog-main-body-box {
        display: flex;
        flex-direction: column;
        width: calc(50% - 10px);
        height: 100%;
        border: 1px solid #cacaca;
        border-radius: 2px;

        .dialog-main-body-box-hd {
            height: 30px;
            padding: 0 5px;
            font-size: 14px;
            font-weight: bold;
            line-height: 30px;
            color: rgba(0, 0, 0, 0.65);
        }

        .dialog-main-body-box-fixed {
            width: 100%;
            padding: 0 3px;
            border-top: 1px solid #cacaca;
        }

        & /deep/ {
            .dialog-main-body-box-content {
                flex-grow: 1;
                height: 0;
                width: 100%;
                padding: 0 5px 5px 5px;
                border-top: 1px solid #cacaca;

                .dialog-box-group {
                    display: block;
                    width: 100%;
                    height: 100%;
                    overflow-x: hidden;
                    overflow-y: auto;
                }
            }

            .dialog-box-group-item {
                display: inline-block;
                margin: 3px;
                height: 30px;
                padding: 0 10px;
                border: 1px dashed #409eff;
                border-radius: 3px;
                line-height: 28px;
                color: rgb(102, 102, 102);
                background-color: #fff;
                cursor: move;
                user-select: none;

                &.is-disabled {
                    background-color: rgb(230, 230, 230);
                    cursor: no-drop;
                }
            }
        }
    }
}

/deep/ .el-dialog .el-dialog__body {
    max-height: none;
}
</style>
